package com.example.filefusion.controller;

import com.example.filefusion.dto.FileInfo;
import com.example.filefusion.service.DownloadService;
import com.example.filefusion.service.FileListService;
import com.example.filefusion.service.FileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.List;

@Controller
public class FileController {

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private FileStorageService fileStorageService;
    
    @Autowired
    private FileListService fileListService;
    
    @Autowired
    private DownloadService downloadService;

    @GetMapping("/")
    public String index(Model model) {
        try {
            logger.info("开始获取文件列表");
            List<FileInfo> fileList = fileListService.listFiles();
            model.addAttribute("fileList", fileList);
            logger.info("成功获取文件列表，文件数量: {}", fileList.size());
        } catch (Exception e) {
            logger.error("获取文件列表失败: {}", e.getMessage(), e);
            model.addAttribute("error", "获取文件列表失败: " + e.getMessage());
        }
        return "index";
    }
    
    @GetMapping("/folder/**")
    @ResponseBody
    public ResponseEntity<List<FileInfo>> getFolderContents(HttpServletRequest request) {
        try {
            // 提取完整的路径参数
            String fullPath = request.getRequestURI().substring("/folder/".length());
            logger.info("开始获取文件夹内容: fullPath={}", fullPath);
            
            // 确保文件夹路径以斜杠结尾
            String prefix = fullPath.endsWith("/") ? fullPath : fullPath + "/";
            List<FileInfo> fileList = fileListService.listFiles(prefix);
            return ResponseEntity.ok(fileList);
        } catch (Exception e) {
            logger.error("获取文件夹内容失败: error={}", e.getMessage(), e);
            // 返回空列表和适当的HTTP状态码
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(List.of());
        }
    }

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
        if (file.isEmpty()) {
            logger.warn("用户尝试上传空文件");
            redirectAttributes.addFlashAttribute("message", "请选择一个文件上传");
            return "redirect:/";
        }

        try {
            logger.info("开始上传文件: originalFilename={}", file.getOriginalFilename());
            String fileName = fileStorageService.uploadFile(file);
            logger.info("文件上传成功: originalFilename={}, storedFileName={}", file.getOriginalFilename(), fileName);
            redirectAttributes.addFlashAttribute("message", "文件上传成功: " + fileName);
        } catch (Exception e) {
            logger.error("文件上传失败: originalFilename={}, error={}", file.getOriginalFilename(), e.getMessage(), e);
            redirectAttributes.addFlashAttribute("message", "文件上传失败: " + e.getMessage());
        }

        return "redirect:/";
    }

    @GetMapping("/download/{filename}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String filename, 
                                                 @RequestHeader(value = "Range", required = false) String rangeHeader) {
        try {
            logger.info("开始下载文件: filename={}, rangeHeader={}", filename, rangeHeader);
            
            // 获取文件大小
            long fileSize = downloadService.getFileSize(filename);
            logger.info("文件大小: filename={}, size={}", filename, fileSize);
            
            if (rangeHeader == null) {
                // 没有Range头，返回整个文件
                logger.info("下载整个文件: filename={}", filename);
                InputStream inputStream = fileStorageService.downloadFile(filename);
                
                HttpHeaders headers = new HttpHeaders();
                headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
                headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileSize));
                headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");
                headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM.toString());

                // 将InputStream包装为Resource
                InputStreamResource resource = new InputStreamResource(inputStream);

                logger.info("文件下载准备完成: filename={}", filename);
                return ResponseEntity.ok()
                        .headers(headers)
                        .body(resource);
            } else {
                // 解析Range头
                // 格式: bytes=start-end
                String[] rangeParts = rangeHeader.replace("bytes=", "").split("-");
                long start = Long.parseLong(rangeParts[0]);
                long end = rangeParts.length > 1 && !rangeParts[1].isEmpty() ? Long.parseLong(rangeParts[1]) : fileSize - 1;
                
                logger.info("下载文件片段: filename={}, range={} - {}", filename, start, end);
                
                // 确保范围有效
                if (start >= fileSize || end >= fileSize) {
                    logger.warn("请求的文件范围无效: filename={}, start={}, end={}, fileSize={}", filename, start, end, fileSize);
                    HttpHeaders headers = new HttpHeaders();
                    headers.add(HttpHeaders.CONTENT_RANGE, "bytes */" + fileSize);
                    return ResponseEntity.status(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE).headers(headers).build();
                }
                
                // 获取文件片段
                InputStream inputStream = downloadService.downloadChunk(filename, start, end);
                
                // 设置响应头
                HttpHeaders headers = new HttpHeaders();
                headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
                headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(end - start + 1));
                headers.add(HttpHeaders.CONTENT_RANGE, "bytes " + start + "-" + end + "/" + fileSize);
                headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");
                headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM.toString());
                
                // 将InputStream包装为Resource
                InputStreamResource resource = new InputStreamResource(inputStream);
                
                logger.info("文件片段下载准备完成: filename={}, range={} - {}", filename, start, end);
                return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
                        .headers(headers)
                        .body(resource);
            }
        } catch (Exception e) {
            logger.error("文件下载失败: filename={}, error={}", filename, e.getMessage(), e);
            return ResponseEntity.badRequest().build();
        }
    }
}